//
//  User.swift
//  LocationTrackerAdmin
//
//  Created by mac on 2025/2/19.
//

import Foundation
import Vapor
import FluentKit
struct User: RouteCollection {
    
    func boot(routes: any RoutesBuilder) throws {
        let group = routes
            .grouped("user")
        group.get("profile", use: self.profile)
        group.get("profileByPhone", use: self.profileByPhone)
        group.post("update", use: self.setProfile)
        group.post("setProfile", use: self.setProfile)
        group.post("exit", use: self.exit)
    }
    
    struct UserProfile: Content {
        let id: String
        let nickName: String
        let avatar: String
        let phone: String
        let latitude: Double
        let longitude: Double
        let detail: String
        let sharing: Bool
        let online: Bool
        let isVIP: Bool
        let vipExpire: TimeInterval?
        let locationPermissions: Int
    }
    @Sendable
    func profile(request: Request) async throws -> JSONResponse<UserProfile> {
        let headers = request.headers
        let deviceID = headers["did"].first ?? ""
        struct UserProfileParam: Codable {
            let id: String
        }
        do {
            let param = try request.query.decode(UserProfileParam.self)
            guard let user = try await UserModel.find(param.id, on: request.db) else {
                throw Abort(.notFound, reason: "User not found")
            }
            let userProfile = UserProfile(
                id: user.id!,
                nickName: user.name,
                avatar: user.avatar,
                phone: user.phone,
                latitude: user.latitude ?? 0,
                longitude: user.longitude ?? 0,
                detail: user.detail ?? "",
                sharing: user.sharing,
                online: user.online,
                isVIP: user.isVIP,
                vipExpire: user.vipExpireDate?.timeIntervalSince1970,
                locationPermissions: user.locationPermissions
            )
            return JSONResponse<UserProfile>(message: "Profile retrieved successfully", code: 0, data: userProfile)
        } catch {
            guard let user = try await UserModel.find(deviceID, on: request.db) else {
                throw Abort(.notFound, reason: "User not found")
            }
            let userProfile = UserProfile(
                id: user.id!,
                nickName: user.name,
                avatar: user.avatar,
                phone: user.phone,
                latitude: user.latitude ?? 0,
                longitude: user.longitude ?? 0,
                detail: user.detail ?? "",
                sharing: user.sharing,
                online: user.online,
                isVIP: user.isVIP,
                vipExpire: user.vipExpireDate?.timeIntervalSince1970,
                locationPermissions: user.locationPermissions
            )
            return JSONResponse<UserProfile>(message: "Profile retrieved successfully", code: 0, data: userProfile)
        }
    }
    
    @Sendable
    func profileByPhone(request: Request) async throws -> JSONResponse<UserProfile> {
        let headers = request.headers
        struct UserProfileParam: Codable {
            let phone: String
        }
        let param = try request.query.decode(UserProfileParam.self)
        if let user = try await UserModel.query(on: request.db)
            .filter(\.$phone == param.phone)
            .first() {
            let userProfile = UserProfile(
                id: user.id!,
                nickName: user.name,
                avatar: user.avatar,
                phone: user.phone,
                latitude: user.latitude ?? 0,
                longitude: user.longitude ?? 0,
                detail: user.detail ?? "",
                sharing: user.sharing,
                online: user.online,
                isVIP: user.isVIP,
                vipExpire: user.vipExpireDate?.timeIntervalSince1970,
                locationPermissions: user.locationPermissions
            )
            return JSONResponse<UserProfile>(message: "Profile retrieved successfully", code: 0, data: userProfile)
        } else {
            let userProfile = UserProfile(
                id: "mock",
                nickName: "",
                avatar: "https://www.gysg168.com:5566/2E336711-D7A3-4743-85DD-8F570B87FB92_file",
                phone: param.phone,
                latitude: 31.22932842411674,
                longitude: 121.50989077799084,
                detail: "上海市黄浦区中山南路187",
                sharing: false,
                online: false,
                isVIP: false,
                vipExpire: nil,
                locationPermissions: 2
            )
            return JSONResponse<UserProfile>(message: "Profile retrieved successfully", code: 0, data: userProfile)
        }
    }
    
    
    @Sendable
    func setProfile(request: Request) async throws -> JSONResponse<Bool> {
        struct UserProfileParam: Content {
            let name: String?
            let phone: String?
            let avatar: String?
            let sharing: Bool?
            let locationPermissions: Int?
        }
        let headers = request.headers
        let deviceID = headers["did"].first ?? ""
        let param = try request.content.decode(UserProfileParam.self)
        //校验一下参数
        guard let user = try await UserModel.query(on: request.db).filter(\.$id == deviceID).first() else {
            throw Abort(.notFound, reason: "User not found")
        }
        if param.name?.isEmpty == false {
            user.name = param.name!
        }
        if param.phone?.isEmpty == false {
            if param.phone?.isPhone ?? false {
                user.phone = param.phone!
            } else {
                return JSONResponse(message: "invalid number", code: -1, data: false)
            }
        }
        if param.avatar?.isEmpty == false {
            user.avatar = param.avatar!
        }
        if let share =  param.sharing {
            user.sharing = share
        }
        if let permissions = param.locationPermissions {
            user.locationPermissions = permissions
        }
        try await user.save(on: request.db)
        return JSONResponse(message: "", code: 0, data: true)
    }
    
    @Sendable
    func exit(request: Request) async throws -> JSONResponse<Bool> {
        let headers = request.headers
        let deviceID = headers["did"].first ?? ""
        try await UserModel.query(on: request.db)
            .filter(\.$id == deviceID)
            .set(\.$online, to: false)
            .update()
        return JSONResponse(message: "退出成功", code: 0, data: true)
    }
}
